const semver = require("semver");
const commander = require("commander");
const userHome = require("user-home");
const path = require("path");
const fsExtra = require("fs-extra");
const dotenv = require("dotenv");
const pathExists = require("path-exists").sync;
const rootCheck = require("root-check");
const colors = require("colors/safe");
const log = require("@cheng-cli-dev/log");
const init = require("@cheng-cli-dev/init");
const exec = require("@cheng-cli-dev/exec");
const pkg = require("../package.json");
const constant = require("./const");

const program = new commander.Command();

async function core() {
  try {
    await prepare();
    registerCommand();
  } catch (e) {
    if (process.env.LOG_LEVEL === "verbose") {
      console.log(e);
    }
    log.error(e.message);
  }
}

async function prepare() {
  checkVersion();
  checkNodeVersion();
  checkRoot();
  checkUserHome();
  // checkInputArgs();
  checkEnv();
  checkGlobalUpdate();
}

//注册命令
function registerCommand() {
  program
    .usage("<command> [options]")
    .name(Object.keys(pkg.bin)[0])
    .version(pkg.version)
    .option("-d, --debug", "是否开启调试模式", false)
    .option("-tp, --targetPath <targetPath>", "是否指定本地调试文件路径", "");

  program
    .command("init [projectName]")
    .option("-f,--force", "是否强制初始化项目")
    .action(exec);

  //开启debug模式
  program.on("option:debug", function () {
    const { debug } = this.opts();
    if (debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
    log.verbose("text");
  });
  program.on("option:targetPath", function () {
    const { targetPath } = this.opts();
    process.env.CLI_TARGET_PATH = targetPath;
  });
  //监听未知命令
  program.on("command:*", function (obj) {
    const avaiableCommand = program.commands.map((cmd) => cmd.name());
    console.log(colors.red(`未知的命令${obj.join(",")}`));
    if (avaiableCommand.length > 0) {
      console.log(colors.red(`可用的的命令${obj.join(",")}`));
    }
  });
  program.parse(process.argv);

  //用户只输入cheng-cli-dev时输入帮助信息
  if (program.args && program.args.length < 1) {
    program.outputHelp();
  }
}

//检测Node版本
function checkNodeVersion() {
  const currentVersion = process.version;
  const lowerNodeVersion = constant.LOWEST_NODE_VERSION;
  if (!semver.gte(currentVersion, lowerNodeVersion)) {
    throw new Error(
      `cheng-cli 需要安装到 v${lowerNodeVersion}以上版本的NodeJs`
    );
  }
}
//检查脚手架版本
function checkVersion() {
  log.info(colors.green("v" + pkg.version));
}
//避免脚手架开发者使用 root 权限进行文件操作，导致其他协作开发者无法对文件进行修改
//尝试降级具有root权限的进程的权限，如果失败，则阻止访问
function checkRoot() {
  rootCheck();
}
//检查主目录
function checkUserHome() {
  if (!pathExists || !pathExists(userHome)) {
    throw new Error(colors.red("当前登录用户主目录不存在！"));
  }
}

//检查环境变量
function checkEnv() {
  const dotenvPath = path.resolve(userHome, ".env");
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath,
    });
  }
  createDefaultEnv();
}
/**
 * 对应env路径
 * @param {string} envPath
 */
function createDefaultEnv() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, constant.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

async function checkGlobalUpdate() {
  //获取当前版本号
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  //调用npm获取所有版本号
  const { getNpmSemverVersion } = require("@cheng-cli-dev/get-npm-info");
  //调取所有版本号进行比较
  const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
  //获取最新版本号提示用户更新到该版本
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(
      colors.yellow(`请手动更新 ${npmName}，当前版本：${currentVersion}，最新版本：${lastVersion}
                更新命令： npm install -g ${npmName}`)
    );
  }
}
module.exports = core;
